home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / Spades.lha / Spades / Source / Spades.c < prev    next >
C/C++ Source or Header  |  1992-04-02  |  15KB  |  455 lines

  1. /**********************************************************
  2. * PROGRAM: Spades                                         *
  3. * AUTHOR: Copyright 1992 Gregory M. Stelmack              *
  4. * COMPILER: SAS/C 5.10b                                   *
  5. *      Copyright (C) 1988 Lattice, Inc.                   *
  6. *      Copyright (C) 1990 SAS Institute, Inc.             *
  7. * VESRION DATES:                                          *
  8. *      Version 1.0  -- February 5, 1990                   *
  9. *      Version 1.1  -- April 28, 1990                     *
  10. *           Images used for cards -- file "Spades.images" *
  11. *           must be in current directory to run.          *
  12. *           Title graphics added. New routine for         *
  13. *           choosing dealer.                              *
  14. *      Version 1.11 -- August 23, 1990                    *
  15. *           Fixed memory freeing bug. Added some prompts. *
  16. *      Version 1.12 -- October 3, 1990                    *
  17. *           Removed LIBRARY_VERSION from OpenLibrary()    *
  18. *           calls, replacing it with zero. An attempt to  *
  19. *           let it run under pre-1.3.                     *
  20. *      Version 1.20 -- April 4, 1991                      *
  21. *           Error messages now pause. Revised strategy.   *
  22. *           Window can be sized and dragged, and screen   *
  23. *           moved to back to allow other things to be     *
  24. *           done.                                         *
  25. *      Version 2.00 -- January 26, 1992                   *
  26. *           Window is now a backdrop, and the screen      *
  27. *           gadgets are visible. Menus now used to select *
  28. *           most options, and rules for NIL bids and Bags *
  29. *           have been added as optional. Computer players *
  30. *           do not yet take these rules into account. Due *
  31. *           to use of EasyRequest() for About, Spades now *
  32. *           requires V36 of Intuition Library (meaning    *
  33. *           you need AmigaDOS 2.xx).                      *
  34. *      Version 2.10 -- February 3, 1992                   *
  35. *           Code clean up. Source broken up into multiple *
  36. *           modules to allow for expansion room. Option to*
  37. *           Save a Hand implemented. Computer strategy    *
  38. *           now accounts for optional rules. More use of  *
  39. *           V36 Library functions (including GadTools).   *
  40. *      Version 2.11 -- March 14, 1992                     *
  41. *           Removed call for EasyRequest() in error       *
  42. *           routine if Intuition did not open. This is to *
  43. *           clean up the GURU if run under 1.3.           *
  44. *      Version 2.12 -- April 2, 1992                      *
  45. *           When a game was started by selecting NewGame, *
  46. *           the game would not quit except from the menu  *
  47. *           (the final screen always continued the game). *
  48. *           Bug fixed.                                    *
  49. **********************************************************/
  50.  
  51. /* Include files */
  52.  
  53. #ifndef INCLUDE_H
  54. #include "Include.h"
  55. #endif
  56.  
  57. #include "Graphics.h"
  58.  
  59. /* Structures needed for libraries */
  60.  
  61. struct IntuitionBase *IntuitionBase;
  62. struct GfxBase       *GfxBase;
  63. struct Library       *DiskfontBase;
  64. struct Library       *GadToolsBase;
  65.  
  66. /* OS Structures */
  67.  
  68. struct Screen       *CustScr;
  69. struct Window       *Wdw;
  70. struct Viewport     *WVP;
  71. APTR                VI;          /* VisualInfo for GadTools */
  72.  
  73. /*************************** Arrays ***************************/
  74. int Deck[52];
  75. int Hand[4][13];
  76. int Bid[4];
  77. int Mode[4];
  78. int HighCardLeft[4];
  79. int Card[4] = {0,0,0,0};
  80. int Value[13];
  81. int SuitNumber[4];
  82. int CardX[4] = {100,1,100,209};
  83. int CardY[4] = {99,60,1,60};
  84. int MsgX[4] = {116,45,116,195};
  85. int MsgY[4] = {96,84,50,84};
  86. BOOL OutOfSuit[4][4];
  87. int TricksTaken[4];
  88. int TrickLeader[14];
  89. int CardPlayed[4][13];
  90.  
  91. /******************** Other Global Variables ******************/
  92. static char *VersionString = "$VER: Spades 2.12 (2-Apr-92)";
  93.  
  94. char *String = "      ";   /* Temporary String Storage */
  95.  
  96. int PlayerScore=0, CompScore=0, PlayerTricks=0, CompTricks=0;
  97. int HandLead=0, Button=0, TrickLead=0, PlayerBid=0, CompBid=0;
  98. int ShortSuit=0, LongSuit=0, HighCard=0, Winner=0;
  99. int PlayerBags=0, CompBags=0;
  100. BOOL SpadePlayed=FALSE, ScreenOpen=FALSE;
  101. BOOL BagsRule=FALSE, NilRule=FALSE, SaveHand=FALSE;
  102. char *CardData;
  103.  
  104. SHORT Mx=0, My=0;        /* Mouse Coordinates */
  105.  
  106. /**************** Module Local Variables and Structures **********/
  107.  
  108. struct EasyStruct    ErrorES =
  109. {
  110.    sizeof(struct EasyStruct),
  111.    0,
  112.    "Spades Error",
  113.    NULL,
  114.    "QUIT"
  115. };
  116.  
  117. /********************* Program Begins Here ********************/
  118.  
  119. /**********************************************************
  120. * Function: main                                          *
  121. * Purpose: Open everything, play the game, close          *
  122. *          everything.                                    *
  123. **********************************************************/
  124. main()
  125. {
  126.    /* Initialize the Amiga */
  127.    
  128.    OpenAll();
  129.    
  130.    /* Start Game */
  131.  
  132.    Spades();
  133.     
  134.    /* Close Everything */
  135.  
  136.    WrapUp();
  137. }
  138.  
  139. /**********************************************************
  140. * Function: OpenAll                                       *
  141. * Parameters: None                                        *
  142. * Return Values: None                                     *
  143. * Purpose: Handle the Amiga initialization                *
  144. **********************************************************/
  145. void OpenAll()
  146. {
  147.    BPTR fh;
  148.    LONG count=0;
  149.    BOOL success;
  150.    
  151.    /* Open the required libraries. */
  152.    
  153.    IntuitionBase = (struct IntuitionBase *) 
  154.       OpenLibrary("intuition.library", 36L);
  155.    if (IntuitionBase == NULL) 
  156.       PError("Can't open Intuition Library");
  157.  
  158.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
  159.    if (GfxBase == NULL)
  160.       PError("Can't open Graphics Library");
  161.  
  162.    GadToolsBase = OpenLibrary("gadtools.library", 36L);
  163.    if (GadToolsBase == NULL)
  164.       PError("Can't open GadTools Library");
  165.       
  166.     /* Load Graphic Images */
  167.  
  168.    CardData = (char *)AllocMem(CARDMEMSIZE,MEMF_CHIP);
  169.    if (!CardData)
  170.       PError("Could not allocate image memory!");
  171.    fh = Open("Spades.images",MODE_OLDFILE);
  172.    if (fh==NULL)
  173.       PError("Can't open images file!");
  174.    count = Read(fh,CardData,CARDMEMSIZE);
  175.    (void)Close(fh);
  176.    if (count==-1)
  177.       PError("Error reading images file!");
  178.  
  179.     /* Open the screen and window */
  180.     
  181.    if ((NewWindowStructure1.Screen = CustScr =
  182.       (struct Screen *)OpenScreen(&NewScreenStructure)) == NULL)
  183.       PError("Can't open new screen");
  184.       
  185.    if (( Wdw = (struct Window *)OpenWindow(&NewWindowStructure1)) == NULL)
  186.    {
  187.       CloseScreen(CustScr);
  188.       PError("Can't open new window");
  189.    }
  190.    
  191.    ScreenOpen = TRUE;
  192.       
  193.     /* Find the viewport and load color map */
  194.  
  195.    WVP = (struct ViewPort *)ViewPortAddress(Wdw);
  196.    LoadRGB4(WVP,&Palette[0],PENS);
  197.  
  198.    /* Create and attach the menu */
  199.  
  200.    VI = GetVisualInfo(CustScr,NULL);
  201.    if (VI == NULL)
  202.       PError("Could not get VisualInfo");
  203.    SpadesMenu = CreateMenus(&SpadesNewMenu[0],GTMN_FrontPen,BLKP);
  204.    if (SpadesMenu == NULL)
  205.       PError("Could not create Menu");
  206.    success = LayoutMenus(SpadesMenu,VI,NULL);
  207.    if (success == FALSE)
  208.       PError("Could not layout Menu");
  209.    SetMenuStrip(Wdw,SpadesMenu);
  210.  
  211.    /* Seed random number generator with TIMER */
  212.  
  213.    srand(time(NULL));
  214. }
  215.  
  216. /**********************************************************
  217. * Function: PError                                        *
  218. * Parameters: s -- pointer to string to print             *
  219. * Return Values: None                                     *
  220. * Purpose: Handle a fatal error                           *
  221. **********************************************************/
  222. void PError(s)
  223. char *s;
  224. {
  225.    ErrorES.es_TextFormat = s;
  226.    
  227.    if (IntuitionBase)
  228.    {
  229.       if (ScreenOpen)
  230.             (void)EasyRequest(Wdw,&ErrorES,NULL,NULL);
  231.       else
  232.             (void)EasyRequest(NULL,&ErrorES,NULL,NULL);
  233.    }
  234.    
  235.    WrapUp();
  236. }
  237.  
  238. /**********************************************************
  239. * Function: WrapUp                                        *
  240. * Parameters: none                                        *
  241. * Return Values: none                                     *
  242. * Purpose: close everything and exit                      *
  243. **********************************************************/
  244. void WrapUp()
  245. {
  246.    if (CardData)      FreeMem((char *)CardData,CARDMEMSIZE);
  247.    if (SpadesMenu)    FreeMenus(SpadesMenu);
  248.    if (Wdw)           CloseWindow(Wdw);
  249.    if (VI)            FreeVisualInfo(VI);
  250.    if (CustScr)       CloseScreen(CustScr);
  251.    if (GfxBase)       CloseLibrary(GfxBase);
  252.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  253.    exit(0);
  254. }
  255.  
  256. /**********************************************************
  257. * Function: Spades                                        *
  258. * Parameters: None                                        *
  259. * Return Values: None                                     *
  260. * Purpose: Play a game of spades. Loop until someone      *
  261. *          scores 500.                                    *
  262. **********************************************************/
  263. void Spades()
  264. {
  265.    /* Loop until player no longer wants to play. */
  266.   
  267.    FOREVER
  268.    {
  269.       PlayerScore=CompScore=0;
  270.       HandLead=FindDealer();
  271.       PlayerBags=CompBags=0;
  272.       
  273.       /* Loop until someone reaches 500 and there is no tie. */
  274.  
  275.       while (((PlayerScore<500)&&(CompScore<500))||
  276.             (PlayerScore==CompScore))
  277.       {
  278.          SetUpScreen();
  279.          InitVars();
  280.          PrintScore();
  281.          DealCards();
  282.          GetBids();
  283.          PrintBids();
  284.          PlayHand();
  285.       }
  286.  
  287.       FinishRoutine();
  288.    }
  289. }
  290.  
  291. /**********************************************************
  292. * Function: FindDealer                                    *
  293. * Parameters: none                                        *
  294. * Return Values: the player determined to initially deal. *
  295. * Purpose: find out who deals first in a game.            *
  296. **********************************************************/
  297. int FindDealer()
  298. {
  299.    int player=0, card=0, i;
  300.    BOOL done=FALSE;
  301.  
  302.    SetRast(RP,BLUP);    /* Clear Screen */
  303.    SetAPen(RP,YELP);
  304.    SetBPen(RP,BLUP);
  305.  
  306.    for (i=0 ; i<52 ; i++) Deck[i]=0;   /* Set deck to undealt */
  307.  
  308.     Move(RP,70,70);         /* Warn player of what's happening */
  309.    Text(RP,"Ace of Spades",13);
  310.    Move(RP,98,78);
  311.    Text(RP,"deals",5);
  312.  
  313.    while(!done)            /* Loop until dealer found */
  314.    {
  315.       while(Deck[card=rand()%52]) ;    /* Find undealt card  */
  316.       Deck[card]=1;                    /* Mark card as dealt */
  317.       DrawCard(CardX[player],CardY[player],card);  /* Draw card */
  318.       Delay(10);           /* Pause */
  319.       if (card==51)        /* Ace of Spades */
  320.       {
  321.          done=TRUE;
  322.          Move(RP,MsgX[player],MsgY[player]);
  323.          Text(RP,"*",1);
  324.       }
  325.       player=(++player)%4;    /* Increment player */
  326.    }
  327.   
  328.    Move(RP,200,150);          /* Wait for player */
  329.    Text(RP,"Click mouse",11);
  330.    ReadMouse();
  331.  
  332.    SetRast(RP,BLUP);
  333.    return((++player)%4);   /* Must return player 2 to left of
  334.                               dealer. Program will later
  335.                               decrement player to find new dealer
  336.                               who should be to left of current dealer */
  337. }
  338.   
  339. /**********************************************************
  340. * Function: InitVars                                      *
  341. * Parameters: none                                        *
  342. * Return Values: none                                     *
  343. * Purpose: Initialize variables and arrays for a new hand.*
  344. **********************************************************/
  345. void InitVars()
  346. {
  347.    int i;
  348.  
  349.    /* Set Leader */
  350.  
  351.    HandLead=(--HandLead+4)%4;
  352.    TrickLead=HandLead;
  353.  
  354.    /* Reset HighCardLeft */
  355.  
  356.    HighCardLeft[0]=12;
  357.    HighCardLeft[1]=12;
  358.    HighCardLeft[2]=12;
  359.    HighCardLeft[3]=12;
  360.    
  361.    /* Reset OutOfSuit */
  362.   
  363.    for (i=0 ; i<4 ; i++)
  364.    {
  365.       OutOfSuit[i][DIAMONDS]=FALSE;
  366.       OutOfSuit[i][CLUBS]   =FALSE;
  367.       OutOfSuit[i][HEARTS]  =FALSE;
  368.       OutOfSuit[i][SPADES]  =FALSE;
  369.    }
  370.   
  371.    /* Determine Modes */
  372.    
  373.    for (i=0 ; i<4 ; i++)
  374.    {
  375.       Mode[i]=0;
  376.       if (i==HandLead) Mode[i]+=2;  /* Leader should bid higher */
  377.       if (i==0||i==2)               /* Human players -- check score */
  378.       {
  379.          if ((PlayerScore>400)&&(CompScore<350)) Mode[i]-=1;
  380.          if (PlayerScore<(CompScore-100)) Mode[i]+=1;
  381.          if (PlayerScore<(CompScore-200)) Mode[i]+=1;
  382.          if (PlayerScore>(CompScore+100)) Mode[i]-=1;
  383.       }
  384.       if (i==1||i==3)               /* Computer players -- check score */
  385.       {
  386.          if ((CompScore>400)&&(PlayerScore<350)) Mode[i]-=1;
  387.          if (CompScore<(PlayerScore-100)) Mode[i]+=1;
  388.          if (CompScore<(PlayerScore-200)) Mode[i]+=1;
  389.          if (CompScore>(PlayerScore+100)) Mode[i]-=1;
  390.       }
  391.    }
  392. }
  393.  
  394. /**********************************************************
  395. * Function: DealCards                                     *
  396. * Parameters: none                                        *
  397. * Return Values: none                                     *
  398. * Purpose: Shuffle & deal the deck to the players.        *
  399. **********************************************************/
  400. void DealCards()
  401. {
  402.    int i,j,player,cardnum[4];
  403.   
  404.    for (i=0 ; i<4 ; i++) cardnum[i]=0; /* Reset cards for each player */
  405.    for (i=0 ; i<52 ; i++) Deck[i]=0;   /* Set whole deck to undealt   */
  406.   
  407.    /* Shuffle and Deal Deck */
  408.   
  409.    for (i=0 ; i<52 ; i++)
  410.    {
  411.       while(Deck[j=rand()%52]) ;    /* Find undealt card */
  412.       Deck[j]=((i/13)+1);           /* Store owning player */
  413.    }
  414.   
  415.    /* Transfer cards to player hands */
  416.  
  417.    for (i=0 ; i<52 ; i++)
  418.    {
  419.       player=Deck[i]-1;                    /* Get owning player */
  420.       Hand[player][cardnum[player]++]=i+1; /* Store card, increment counter */
  421.    }
  422. }
  423.  
  424. /**********************************************************
  425. * Function: itoa                                          *
  426. * Parameters: n -- number to convert                      *
  427. *             s -- pointer to result string               *
  428. * Return Values: none                                     *
  429. * Purpose: Convert an integer to a string so it can be    *
  430. *          used by the Text function. Lattice does not    *
  431. *          have one.                                      *
  432. **********************************************************/
  433. void itoa(n,s)
  434. char *s;
  435. int n;
  436. {
  437.    int i=0;
  438.    BOOL sign=FALSE;
  439.   
  440.    if (n<0)
  441.    {
  442.       sign=TRUE;
  443.       n=-n;
  444.    }
  445.  
  446.    do
  447.    {
  448.       s[i++]=n%10+'0';
  449.    } while((n/=10)>0);
  450.  
  451.    if (sign) s[i++]='-';
  452.    s[i]='\0';
  453.    strrev(s);
  454. }
  455.